import 'package:audio_video_progress_bar/audio_video_progress_bar.dart';
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
import 'package:rxdart/rxdart.dart';

var themeNotifier = ValueNotifier<ThemeVariation>(
  ThemeVariation(Colors.blue, Brightness.light),
);

class ThemeVariation {
  const ThemeVariation(this.color, this.brightness);

  final MaterialColor color;
  final Brightness brightness;
}

class AudioPlayerWidget extends StatefulWidget {
  final String audioUrl;
  final TimeLabelLocation location;

  const AudioPlayerWidget({Key? key, required this.audioUrl, this.location = TimeLabelLocation.sides})
      : super(key: key);

  @override
  _AudioPlayerWidgetState createState() => _AudioPlayerWidgetState();
}

class _AudioPlayerWidgetState extends State<AudioPlayerWidget> {
  late AudioPlayer _player;
  late Stream<DurationState> _durationState;
  var _labelLocation = TimeLabelLocation.sides;
  final _labelType = TimeLabelType.totalTime;

  @override
  void initState() {
    _labelLocation = widget.location;
    super.initState();
    _player = AudioPlayer();
    _durationState = Rx.combineLatest2<Duration, PlaybackEvent, DurationState>(
        _player.positionStream,
        _player.playbackEventStream,
        (position, playbackEvent) => DurationState(
              progress: position,
              buffered: playbackEvent.bufferedPosition,
              total: playbackEvent.duration,
            ));
    _init();
  }

  Future<void> _init() async {
    try {
      await _player.setUrl(widget.audioUrl);
    } catch (e) {
      print("An error occured $e");
    }
  }

  @override
  void dispose() {
    _player.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        _playButton(),
        Expanded(child: _progressBar()),
      ],
    );

    // child: Column(
    //   mainAxisSize: MainAxisSize.min,
    //   children: [
    //     _themeButtons(),
    //     _labelLocationButtons(),
    //     _labelTypeButtons(),
    //     Spacer(),
    //     _progressBar(),
    //     _playButton(),
    //   ],
    // ),
  }

  StreamBuilder<DurationState> _progressBar() {
    return StreamBuilder<DurationState>(
      stream: _durationState,
      builder: (context, snapshot) {
        final durationState = snapshot.data;
        final progress = durationState?.progress ?? Duration.zero;
        final buffered = durationState?.buffered ?? Duration.zero;
        final total = durationState?.total ?? Duration.zero;
        return ProgressBar(
          progress: progress,
          buffered: buffered,
          total: total,
          barHeight: 3,
          thumbRadius: 8,
          baseBarColor: Colors.black12,
          progressBarColor: Colors.black87,
          bufferedBarColor: Colors.black45,
          thumbColor: Colors.black,
          onSeek: (duration) {
            _player.seek(duration);
          },
          timeLabelLocation: _labelLocation,
          timeLabelType: _labelType,
        );
      },
    );
  }

  StreamBuilder<PlayerState> _playButton() {
    return StreamBuilder<PlayerState>(
      stream: _player.playerStateStream,
      builder: (context, snapshot) {
        final playerState = snapshot.data;
        final processingState = playerState?.processingState;
        final playing = playerState?.playing;
        if (processingState == ProcessingState.loading || processingState == ProcessingState.buffering) {
          return Container(
            margin: EdgeInsets.symmetric(horizontal: 4),
            width: 26.0,
            height: 26.0,
            child: CircularProgressIndicator(
              strokeWidth: 2,
            ),
          );
        } else if (playing != true) {
          return IconButton(
            padding: const EdgeInsets.all(4),
            icon: Icon(Icons.play_arrow),
            iconSize: 26.0,
            onPressed: _player.play,
          );
        } else if (processingState != ProcessingState.completed) {
          return IconButton(
            padding: const EdgeInsets.all(4),
            icon: Icon(Icons.pause),
            iconSize: 26.0,
            onPressed: _player.pause,
          );
        } else {
          return IconButton(
            padding: const EdgeInsets.all(6),
            icon: Icon(Icons.replay),
            iconSize: 24.0,
            onPressed: () => _player.seek(Duration.zero),
          );
        }
      },
    );
  }
}

class DurationState {

  final Duration progress;
  final Duration buffered;
  final Duration? total;
  const DurationState({
    required this.progress,
    required this.buffered,
    this.total,
  });

}
